<template>
  <div style="width:100%;overflow:hidden;position:relative">
    <img src="../../lib/surf/whitehouse1.jpg" style="position:absolute;top:50%;left:50%;z-index:-1;transform:translate(-50%,-50%);max-width:100%;max-height:100%;width:auto;height:auto;">
    <!--<img src="../../lib/surf/whitehouse2.jpg" style="width:100%">-->
  </div>
</template>

<script>
import Surf from '../../lib/surf/Surf'
import POS from '../lib/ar/posit1-patched'
const THREE = require('three')

export default {
  mounted() {
    var domWidth = window.innerWidth
	var domHeight = window.innerHeight - 44
	
    var img = this.$el.querySelector('img')
	var srcWidth = img.naturalWidth
	var srcHeight = img.naturalHeight
	
	// init scene and camera
	var scene = new THREE.Scene()
	var camera = new THREE.PerspectiveCamera(40, domWidth / domHeight, 0.01, 1000)
	camera.position.z = 0
  
    // init renderer
	var renderer = new THREE.WebGLRenderer({
		antialias: true,
		alpha: true,
	})
	renderer.setSize(domWidth, domHeight)
	// renderer.setPixelRatio(window.devicePixelRatio)
	// renderer.setClearColor(0x000000, 0)
	this.$el.appendChild(renderer.domElement)
	
	// array of functions for the rendering loop
	var onRenderFcts = []
	
	// render the scene
	onRenderFcts.push(() => {
	  renderer.render(scene, camera)
	})

	function render() {
      requestAnimationFrame(render)
	  onRenderFcts.forEach(onRenderFct => {
		onRenderFct()
	  })
    }
	render()
    
	var object3d = new THREE.Object3D()
	scene.add(object3d)
	
	;(function(){
	  var corners = [{
	    x: 63,
	    y: 47
	  },{
	    x: 94,
	    y: 47
	  },{
	    x: 96,
	    y: 70
	  },{
	    x: 59,
	    y: 70
	  }],
	  canvasWidth = 163,
	  canvasHeight = 122
	  for(var i = 0; i < corners.length; ++i) {
	  	corners[i].x = corners[i].x - (canvasWidth / 2)
	  	corners[i].y = (canvasHeight / 2) - corners[i].y
	  }
	  
	  var modelSize = 35.0
	  
	  // compute the pose from the canvas
	  var posit = new POS.Posit(modelSize, canvasWidth);
	  var pose = posit.pose(corners);
	  if(pose === null)
	    return;
	
	  // Translate pose to THREE.Object3D
	  var rotation = pose.bestRotation
	  var translation = pose.bestTranslation

	  object3d.scale.x = modelSize;
	  object3d.scale.y = modelSize;
	  object3d.scale.z = modelSize;

	  object3d.rotation.x = -Math.asin(-rotation[1][2]);
	  object3d.rotation.y = -Math.atan2(rotation[0][2], rotation[2][2]);
	  object3d.rotation.z = Math.atan2(rotation[1][0], rotation[1][1]);
      
	  object3d.position.x = translation[0];
	  object3d.position.y = translation[1];
	  object3d.position.z = -translation[2];
    })()
  
    // set 3 point lighting
    ;(function(){
	  var object3d = new THREE.AmbientLight(0x101010)
	  object3d.name = 'Ambient light'
	  scene.add(object3d)
	  
	  var object3d = new THREE.DirectionalLight('white', 0.1 * 1.6)
	  object3d.position.set(2.6, 1, 3).setLength(1)
	  object3d.name = 'Back light'
	  scene.add(object3d)
      
	  var object3d = new THREE.DirectionalLight('white', 0.375 * 1.6)
	  object3d.position.set(-2, -1, 0)
	  object3d.name = 'Key light'
	  scene.add(object3d)
	  
	  var object3d = new THREE.DirectionalLight('white', 0.8 * 1)
	  object3d.position.set(3, 3, 2)
	  object3d.name = 'Fill light'
	  scene.add(object3d)
	})()
	
	// add some debug display
	;(function(){
	  var geometry = new THREE.PlaneGeometry(1, 1, 10, 10)
	  var material = new THREE.MeshBasicMaterial( {
	  	wireframe: true
	  })
	  var mesh = new THREE.Mesh(geometry, material);
	  object3d.add( mesh );
      
	  var mesh = new THREE.AxisHelper
	  object3d.add( mesh );
	})()
	
	function getLine(points) {
	  var a = 1, b = 0, c = Number.MAX_VALUE
	  var index0 = null, index1 = null
	  points.forEach((point, index) => {
	    if(index0 == null || point.x < points[index0].x) {
		  index0 = index
		}
	  })
	  points.forEach((point, index) => {
	    if(index == index0) {
		  return
		}
		if(index1 == null || (c - b * point.y) / a > point.x) {
		  index1 = index
		  a = points[index0].y - points[index1].y
		  b = points[index1].x - points[index0].x
		  c = points[index1].x * points[index0].y - points[index0].x * points[index1].y
	      if(c != 0) {
	        a /= c
	        b /= c
	        c = 1
	      }
		}
	  })
	  return {
	    a,
		b,
		c
	  }
	}
  
	  var points = []
	  for(var i=4; i>0; i--) {
		var point = {
		  x: Math.random() * srcWidth,
		  y: Math.random() * srcHeight
		}
		points.push(point)
	  }
	  var left = getLine(points)
	  
	  var _points = []
	  points.forEach(point => {
	    _points.push({
		  x: -point.x,
		  y: point.y
		})
	  })
	  var right = getLine(_points)
	  right.a = -right.a
	  
	  var _points = []
	  points.forEach(point => {
	    _points.push({
		  x: -point.y,
		  y: point.x
		})
	  })
	  var _top = getLine(_points)
	  var top = {
	    a: _top.b,
		b: -_top.a,
        c: _top.c		
	  }
	  
	  var _points = []
	  points.forEach(point => {
	    _points.push({
		  x: point.y,
		  y: point.x
		})
	  })
	  var _bottom = getLine(_points)
	  var bottom = {
	    a: _bottom.b,
		b: _bottom.a,
        c: _bottom.c		
	  }
	  
	  var topLeft = {
	    x: (top.c * left.b - left.c * top.b) / (top.a * left.b - left.a * top.b),
		y: (top.c * left.a - left.c * top.a) / (top.b - left.a - left.b * top.a)
	  }
	  console.log(top)
	  console.log(left)
	  console.log(topLeft)
	
    onRenderFcts.push(() => {
	  return
	  var canvasElement = document.createElement('canvas')
	  var context = canvasElement.getContext('2d')
	  
	  canvasElement.width = imgs[0].naturalWidth
	  canvasElement.height = imgs[0].naturalHeight
	  context.drawImage(imgs[0], 0, 0, canvasElement.width, canvasElement.height)
	  var imageData = context.getImageData(0, 0, canvasElement.width, canvasElement.height)
	  var surf0 = new Surf(imageData)
	  
	  canvasElement.width = imgs[1].naturalWidth
	  canvasElement.height = imgs[1].naturalHeight
	  context.drawImage(imgs[1], 0, 0, canvasElement.width, canvasElement.height)
	  var imageData = context.getImageData(0, 0, canvasElement.width, canvasElement.height)
	  var surf1 = new Surf(imageData)
	  
	  var match = surf0.getMatchingPoints(surf1, true);
	  console.log(match.length)
	  match.forEach(item => {
	  	var point0 = item[0],
	  	point1 = item[1];
	  	console.log(point0.getX() + ' ' + point0.getY() + ' = '  + point1.getX() + ' ' + point1.getY())
	  })
	})
  }
}
</script>